/**
 * @internal
 * @file utest.cpp
 * @brief Тестровое приложение для qua::ustring
 * @details Тесты ввода/вывода различных кодировок
 * @version 1.0
 * @date 12 августа 2011
 * @author Владимир Керимов
 * @endinternal
 */

#include <qua/ustring.h>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <conio.h>

#include <test/cp866.hpp>
#include <test/cp1250.hpp>
#include <test/cp1251.hpp>
#include <test/cp1252.hpp>
#include <test/utf8.hpp>
#ifdef _MSC_VER
#include <test/utf16_msc.hpp>
#else
#include <test/utf16_gcc.hpp>
#endif

using qua::encode;

void waitkey()
{
    std::cout << "\nPress any key... " << std::flush;
    _getch();
}

void showcodes( const char* sptr )
{
    int len = std::strlen( sptr );
    std::cout << "{ " << std::hex;
    for( int i = 0; i < len; i++ )
        std::cout << std::setw( 2 ) << std::setfill( '0' )
                  << (int)( sptr[i] & 0xFF ) << ( i < len - 1 ? ", " : " }" );
    std::cout << std::endl;
}

void showcodes( const wchar_t* wcsptr )
{
    int len = std::wcslen( wcsptr );
    std::cout << "{ " << std::hex;
    for( int i = 0; i < len; i++ )
        std::cout << std::setw( 4 ) << std::setfill( '0' )
                  << (int)( wcsptr[i] & 0xFFFF ) << ( i < len - 1 ? ", " : " }" );
    std::cout << std::endl;
}

int main( int argc, char *argv[] )
{
    std::atexit( waitkey );

    std::cout << "Unicode string test\nVersion 1.0\n" << std::endl;

    if( argc < 2 )
    {
        std::cout << "ERROR! Argument of code page expected!" << std::endl;
        return -1;
    }

    try
    {
        try
        {
            encode::codepage cp = encode::read_codepage( argv[1] );
            encode::set_default_codepage( cp );
        }
        catch( std::exception& )
        {
            encode::codepage cp = static_cast< encode::codepage >( std::atoi( argv[1] ) );
            encode::set_default_codepage( cp );
        }

        qua::ustring strUTF16 = qua::to_ustring( test::utf16_str );
        std::cout << strUTF16 << std::endl;
        showcodes( test::utf16_str );

        qua::ustring str866 = qua::to_ustring( test::cp866_str, encode::cp866 );
        std::cout << str866 << std::endl;
        showcodes( test::cp866_str );

        qua::ustring str1250 = qua::to_ustring( test::cp1250_str, encode::cp1250 );
        std::wcout << str1250 << std::endl;
        showcodes( test::cp1250_str );

        qua::ustring str1251 = qua::to_ustring( test::cp1251_str, encode::cp1251 );
        std::cout << str1251 << std::endl;
        showcodes( test::cp1251_str );

        qua::ustring str1252 = qua::to_ustring( test::cp1252_str, encode::cp1250 );
        std::wcout << str1252 << std::endl;
        showcodes( test::cp1252_str );

        qua::ustring strUTF8 = qua::to_ustring( test::utf8_str, encode::UTF8 );
        std::cout << strUTF8 << std::endl;
        showcodes( test::utf8_str );
    }
    catch( std::exception& e )
    {
        std::cout << e.what() << std::endl;
        return -1;
    }
    catch( ... )
    {
        std::cout << "ERROR! Unexpected exception occurs!";
        return -1;
    }

    return 0;
}
